package com.dw.library.view;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;

import com.dw.library.R;

/**
 * 
 */
public class TextIndicator extends AbsViewPagerIndicator {
  private static final String TAG = "TextViewPagerIndicator";

  private String[] titles;

  private float mEdgeH;
  private float mIndicatorH;
  private float mIndicatorEdge; // 标题与指示器之间间隔
  private float mIndicatorTopMargin;
  private float mTextPadding; // 标题之间最小间隔
  private float mTextSize; // px

  private Paint mPaint;
  private int mCenterTitleIdx = 0;

  public TextIndicator(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    super.setOrientation(ORIENTATION_HORIZONTAL);
    super.setItemW(50);
    
    Resources res = this.getResources();
    final float defTextSize = res.getDimension(R.dimen.def_ti_text_size);
    final float defTextPadding = res.getDimension(R.dimen.def_ti_text_padding);
    final float defIndicatorH = res.getDimension(R.dimen.def_ti_indicator_height);
    final float defIndicatorEdge = res.getDimension(R.dimen.def_ti_indicator_edge);
    final float defIndicatorTopMargin = res.getDimension(R.dimen.def_ti_indicator_top_margin);
    final float defEdgeH = res.getDimension(R.dimen.def_ti_edge_height);
    
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TextIndicator);
    mTextSize = array.getDimension(R.styleable.TextIndicator_tiTextSize, defTextSize);
    mTextPadding = array.getDimension(R.styleable.TextIndicator_tiTextPadding, defTextPadding);
    mIndicatorH = array.getDimension(R.styleable.TextIndicator_tiIndicatorHeight, defIndicatorH);
    mIndicatorEdge = array.getDimension(R.styleable.TextIndicator_tiIndicatorEdge, defIndicatorEdge);
    mIndicatorTopMargin = array.getDimension(R.styleable.TextIndicator_tiIndicatorTopMargin, defIndicatorTopMargin);
    mEdgeH = array.getDimension(R.styleable.TextIndicator_tiEdgeHeight, defEdgeH);
    array.recycle();
    
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.parseColor("#006600"));
    mPaint.setTextSize(mTextSize);
  }

  public TextIndicator(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public TextIndicator(Context context) {
    this(context, null);
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(null == mViewPager.getAdapter() || null == titles || mViewPager.getAdapter().getCount() != titles.length){
      return ;
    }
    
    mPaint.setAlpha(255);
    final int width = this.getWidth();
    final int height = this.getHeight();
    String text = null;
    float len = 0;
    float y = this.getPaddingTop() + mTextSize;
    float x = 0;
    
    // 画中间标题
    text = titles[mCenterTitleIdx];
    len = mPaint.measureText(text);
    float moveDis = (width - len) / 2;

    /**
     * positionOffset变化过程 
     * 标题向右：                            1.0 --> 0.5 
     *         0.5 --> 0.0 
     * 标题向左：    0.5 <-- 0.0 
     *                 1.0 <-- 0.5
     */
    //透明度比率
    float alpha = Math.abs(0.5f - mPositionOffset) / 0.5f;
    if (mPositionOffset < 0.5) {
      x = moveDis * alpha;
    } else {
      x = 2 * moveDis - moveDis * alpha;
    }
    canvas.drawText(text, x, y, mPaint);
    
    //画前一个标题
    if(mCenterTitleIdx > 0){
      text = titles[mCenterTitleIdx-1];
      float length = mPaint.measureText(text);
      if(x >= length + mTextPadding){
        canvas.drawText(text, 0, y, mPaint);
      }else if(x > mTextPadding){
        canvas.drawText(text, x - length - mTextPadding, y, mPaint);
      }
    }
    
    //画后一个标题
    if(mCenterTitleIdx < titles.length - 1){
      text = titles[mCenterTitleIdx+1];
      float length = mPaint.measureText(text);
      float f = width - x;
      if(f >= len + length + mTextPadding){
        canvas.drawText(text, width - length, y, mPaint);
      }else if(f > len + mTextPadding){
        canvas.drawText(text, x + len + mTextPadding, y, mPaint);
      }
    }
    
    float edgeTop = height - mEdgeH;
    canvas.drawRect(0, edgeTop, width, height, mPaint);
    int paintAlpha = (int)(alpha*255);
    mPaint.setAlpha(paintAlpha);
    canvas.drawRect(x - mIndicatorEdge, edgeTop - mIndicatorH*alpha, x + len + mIndicatorEdge, edgeTop, mPaint);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
  }

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    if (mPositionOffset < 0.5) {
      mCenterTitleIdx = mCurrentPage;
    } else {
      mCenterTitleIdx = mCurrentPage + 1;
    }
    super.onPageScrolled(position, positionOffset, positionOffsetPixels);
  }

  @Override
  public void onPageSelected(int position) {
    mCenterTitleIdx = position;
    super.onPageSelected(position);
  }

  public void setViewPager(ViewPager view, String[] titles){
    if(null == view.getAdapter() || null == titles || view.getAdapter().getCount() != titles.length){
      return ;
    }
    this.titles = titles;
    super.setViewPager(view);
  }
  
  public void setTitles(String[] titles){
    if(null != titles){
      this.titles = titles;
    }
  }

  @Override
  public void setOrientation(int orientation) {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  public void setGravity(int gravity) {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  public float getInternalPadding() {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  public void setInternalPadding(float internalPadding) {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  public float getItemW() {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  public void setItemW(float itemW) {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  public float getItemH() {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  public void setItemH(float itemH) {
    throw new RuntimeException("该方法不可用");
  }

  @Override
  protected void drawBackground(Canvas canvas, float left, float top, float right, float bottom) {
  }

  @Override
  protected void drawIndicator(Canvas canvas, float left, float top, float right, float bottom) {
  }
  
  public float getEdgeH() {
    return mEdgeH;
  }

  public void setEdgeH(float edgeH) {
    this.mEdgeH = edgeH;
    invalidate();
  }

  public float getIndicatorH() {
    return mIndicatorH;
  }

  public void setIndicatorH(float indicatorH) {
    this.mIndicatorH = indicatorH;
    invalidate();
  }

  public float getIndicatorEdge() {
    return mIndicatorEdge;
  }

  public void setIndicatorEdge(float indicatorEdge) {
    this.mIndicatorEdge = indicatorEdge;
    invalidate();
  }

  public float getIndicatorTopMargin() {
    return mIndicatorTopMargin;
  }

  public void setmIndicatorTopMargin(float indicatorTopMargin) {
    this.mIndicatorTopMargin = indicatorTopMargin;
    invalidate();
  }

  public float getTextPadding() {
    return mTextPadding;
  }

  public void setTextPadding(float textPadding) {
    this.mTextPadding = textPadding;
    invalidate();
  }

  public float getTextSize() {
    return mTextSize;
  }

  public void setTextSize(float textSize) {
    this.mTextSize = textSize;
    mPaint.setTextSize(textSize);
    invalidate();
  }

  private int measureWidth(int measureSpec) {
    int result;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    if ((specMode == MeasureSpec.EXACTLY)) {
      // We were told how big to be
      result = specSize;
    } else {
      // Calculate the width according the views count
      result = this.getResources().getDisplayMetrics().widthPixels;
      // Respect AT_MOST value if that was what is called for by measureSpec
      if (specMode == MeasureSpec.AT_MOST) {
        result = Math.min(result, specSize);
      }
    }
    return result;
  }

  /**
   * Determines the height of this view
   * 
   * @param measureSpec
   *          A measureSpec packed into an int
   * @return The height of the view, honoring constraints from measureSpec
   */
  private int measureHeight(int measureSpec) {
    int result;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    if (specMode == MeasureSpec.EXACTLY) {
      // We were told how big to be
      result = specSize;
    } else {
      // Measure the height
      result = (int) (mTextSize + mIndicatorTopMargin + mIndicatorH + mEdgeH + getPaddingTop() + getPaddingBottom() + 1);
      // Respect AT_MOST value if that was what is called for by measureSpec
      if (specMode == MeasureSpec.AT_MOST) {
        result = Math.min(result, specSize);
      }
    }
    return result;
  }
}
